{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Albumentations Integration for Anomaly Detection\n",
    "\n",
    "In this notebook, we will explore **FiftyOne’s integration with Albumentations**, a powerful image augmentation library. \n",
    "Augmentations can significantly enhance **anomaly detection** models by improving robustness and generalization.\n",
    "\n",
    "![albumentation](https://cdn.voxel51.com/getting_started_manufacturing/notebook6/albumentation.webp)\n",
    "\n",
    "## Learning Objectives:\n",
    "- Understand the importance of **data augmentation** for anomaly detection.\n",
    "- Use **Albumentations** to apply transformations to datasets in FiftyOne.\n",
    "- Explore different augmentation techniques for improving model performance."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Why Use Augmentations for Anomaly Detection?\n",
    "\n",
    "Anomaly detection models often struggle due to **limited data availability** and **environmental variations**. \n",
    "Data augmentation helps by:\n",
    "- **Simulating real-world variations** (e.g., lighting changes, noise, blur).\n",
    "- **Increasing dataset diversity**, reducing overfitting.\n",
    "- **Improving model robustness** to unseen conditions.\n",
    "\n",
    "Albumentations allows us to apply **realistic transformations**, such as:\n",
    "- **Brightness and contrast adjustments** (simulate different lighting conditions).\n",
    "- **Color jittering** (alter hue, saturation, and intensity).\n",
    "- **Gaussian noise, blur, and distortions** (improve generalization).\n",
    "\n",
    "**Relevant Documentation:** \n",
    "- [Albumentations Documentation](https://albumentations.ai/docs/)\n",
    "- [Why Data Augmentation Matters](https://docs.voxel51.com/integrations/albumentations.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install -U albumentations==1.4.24 fiftyone"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!fiftyone plugins download https://github.com/jacobmarks/fiftyone-albumentations-plugin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import gdown\n",
    "\n",
    "url = \"https://drive.google.com/uc?id=1nAuFIyl2kM-TQXduSJ9Fe_ZEIVog4tth\" # original\n",
    "gdown.download(url, output=\"mvtec_ad.zip\", quiet=False)\n",
    "\n",
    "!unzip mvtec_ad.zip\n",
    "\n",
    "import fiftyone as fo \n",
    "\n",
    "dataset_name = \"MVTec_AD\"\n",
    "\n",
    "# Check if the dataset exists\n",
    "if dataset_name in fo.list_datasets():\n",
    "    print(f\"Dataset '{dataset_name}' exists. Loading...\")\n",
    "    dataset = fo.load_dataset(dataset_name)\n",
    "else:\n",
    "    print(f\"Dataset '{dataset_name}' does not exist. Creating a new one...\")\n",
    "    dataset_ = fo.Dataset.from_dir(\n",
    "        dataset_dir=\"/content/mvtec-ad\",\n",
    "        dataset_type=fo.types.FiftyOneDataset\n",
    "    )\n",
    "    dataset = dataset_.clone(\"MVTec_AD\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Try this for already loaded dataset\n",
    "# dataset = fo.load_dataset('mvtec-ad-staging')\n",
    "OBJECTS_LIST = [\n",
    "    'pill',\n",
    "    'zipper',\n",
    "    'tile',\n",
    "    'bottle',\n",
    "    'transistor',\n",
    "    'wood',\n",
    "    'cable',\n",
    "    'capsule',\n",
    "    'carpet',\n",
    "    'grid',\n",
    "    'hazelnut',\n",
    "    'leather',\n",
    "    'metal_nut',\n",
    "    'screw',\n",
    "    'toothbrush'\n",
    "]\n",
    "OBJECT = \"screw\" ## object to select"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from fiftyone import ViewField as F # helper for defining views\n",
    "\n",
    "# Define the new dataset name for split set\n",
    "dataset_name_split = \"mvtec-screw\"\n",
    "\n",
    "if dataset_name_split in fo.list_datasets():\n",
    "    print(f\"Dataset '{dataset_name_split}' exists. Loading...\")\n",
    "    mvtec_screw = fo.load_dataset(dataset_name_split)\n",
    "else:\n",
    "    print(f\"Dataset '{dataset_name_split}' does not exist. Creating a new one...\")\n",
    "    ## get the test split of the dataset\n",
    "    test_split = dataset.match(F(\"category.label\") == 'screw')\n",
    "\n",
    "    # Clone the dataset into a new one called \"mvtec_bottle\"\n",
    "    mvtec_screw = test_split.clone(\"mvtec-screw\", persistent=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(mvtec_screw)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "session = fo.launch_app(mvtec_screw, port=5156, auto=False)\n",
    "print(session.url)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to manipulate Plugins\n",
    "\n",
    "[Here](https://docs.voxel51.com/plugins/using_plugins.html#managing-plugins) is a guide you can follow to check your plugins, enable, disable or delete those. "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "env",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
